import numpy as np
from .normalize import normalize
from .generate_sinusoids import generate_sinusoids
from .generate_polynomials import generate_polynomials

"""
数据预处理的函数prepare_for_training。
接受一个数据集作为输入，并根据给定的参数进行预处理操作
"""


def prepare_for_training(data, polynomial_degree=0, sinusoid_degree=0, normalize_data=True):
    # 计算样本总数
    num_examples = data.shape[0]
    # 创建一个数据副本data_processed，以便在进行预处理操作时不改变原始数据
    data_processed = np.copy(data)

    # 预处理
    features_mean = 0
    features_deviation = 0
    data_normalized = data_processed
    # 如果normalize_data参数为True，则对数据进行归一化处理
    # 归一化操作将数据的每个特征缩放到0和1之间，
    # 以消除不同特征之间的量纲差异。同时，记录特征的均值和标准差
    if normalize_data:
        (
            data_normalized,
            features_mean,
            features_deviation
        ) = normalize(data_processed)

        data_processed = data_normalized

    # 特征变换sinusoidal
    # 如果sinusoid_degree大于0，则进行正弦特征变换
    if sinusoid_degree > 0:
        # generate_sinusoids函数用于生成指定阶数的正弦特征，并将其与原始数据进行连接。
        sinusoids = generate_sinusoids(data_normalized, sinusoid_degree)
        data_processed = np.concatenate((data_processed, sinusoids), axis=1)

    # 特征变换polynomial
    # 如果polynomial_degree大于0，则进行多项式特征变换
    if polynomial_degree > 0:
        # generate_polynomials函数用于生成指定阶数的多项式特征，并将其与原始数据进行连接
        polynomials = generate_polynomials(data_normalized, polynomial_degree, normalize_data)
        data_processed = np.concatenate((data_processed, polynomials), axis=1)

    # 加一列1,将一个全为1的列向量添加到数据的左侧，以便在训练模型时考虑截距
    data_processed = np.hstack((np.ones((num_examples, 1)), data_processed))
    # 返回经过预处理后的数据data_processed，以及特征的均值features_mean和标准差features_deviation
    return data_processed, features_mean, features_deviation